{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d5d54120",
   "metadata": {},
   "source": [
    "Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n",
    "SPDX-License-Identifier: Apache-2.0\n",
    "\n",
    "# Fraud Ring Identification\n",
    "\n",
    "Within the financial industry, an organization can expect to lose 3-6%, and up to 10%, of its [business to fraudulent activities](http://www.crowe.ie/wp-content/uploads/2019/08/The-Financial-Cost-of-Fraud-2019.pdf).  Fraudulent activities not only impact financial aspects, but victims often have negative views of the company, leading to negative market sentiment.  Overall, fraudulent activities has a significant impact on a business, in terms of both consumer confidence and bottom-line revenue.  Due to the impact of these illicit activities on the bottom line, companies expend significant time and money to detect and prevent fraud.  \n",
    "\n",
    "When dealing with fraud, there are two main components to a robust fraud system: fraud detection and fraud prevention.  In the fraud detection component of a system, the main goals are to develop a system and methodology that allows for the rapid discovery of fraudulent activities.   This usually involves a posterior evaluation of data, such as transactions, users, credit cards, etc. to determine what patterns or combinations represent actual fraud.  This process usually involves a human-in-the-loop system where automated processes flag likely or potential fraudulent activities, which are then evaluated by an expert in the domain to determine the legitimacy, or illegitimacy, of the activities flagged.  The output of this process is a set of known and evolving patterns of fraud that are fed into a fraud prevention system.   In this notebook we will focus on finding one type of pattern, fraud rings.\n",
    "\n",
    "## What is a Fraud Ring\n",
    "\n",
    " A fraud ring refers to a group of people who work together to commit various types of fraud or scams, often targeting businesses or individuals for financial gain. Some key characteristics of a fraud ring include:\n",
    "\n",
    "* Organization - The group has a structure and hierarchy, with different members having specific roles in carrying out the fraud. There is often a ringleader organizing the operations.\n",
    "\n",
    "* Collaboration - Members of the ring work together and share information/resources to facilitate the fraud. Their combined skills and knowledge make the fraud harder to detect.\n",
    "\n",
    "* Specialization - Each member specializes in a specific type of fraud or scam, or handles a certain part of the operation. This division of roles makes the ring more efficient.\n",
    "\n",
    "* Inside contacts - Fraud rings often recruit or bribe insiders who can provide sensitive information or access to facilitate the fraud.\n",
    "\n",
    "* Multiple schemes - Rings typically run various interconnected fraud schemes simultaneously to maximize financial gain. \n",
    "\n",
    "* Sophistication - Rings use increasingly advanced techniques to avoid detection, such as identity theft, forgery, money laundering, hacking, and more.\n",
    "\n",
    "* Large scale - Fraud rings are able to operate fraud at a much larger scale than individuals. The financial damage can amount to millions.\n",
    "\n",
    "To summarize, a fraud ring is a structured criminal enterprise that works in a coordinated manner to pull off major frauds against businesses, government programs, or unsuspecting individuals. Breaking up these rings requires following the money trail and connections between members.\n",
    "\n",
    "A fraud ring can operate under one of several pretexts. One common premise involves forgery, in which the fraud ring will create fake claims, steal identities and even print counterfeit checks and currency. Some rings target individuals, committing identity theft and the like, but many will focus on targeting e-commerce websites, businesses, charities or government agencies. The fraud rings will often test their software against the business’s payment solutions by trying to make purchases through bogus gift cards or by using fake credit cards. If the fraud ring can get past the first line of defense the business has in place, it will move on to more severe crimes against the business, including larger purchases paid for via fraudulent means, hacking into the company’s database and stealing the personal details of their customers and more. \n",
    "\n",
    "\n",
    "## Challenges of Detecting Fraud Rings\n",
    "\n",
    "When dealing with fraud, it is often helpful to understand some challenges of finding fraudulent activities when looking into data.  Often this is aided by first understanding the definition and nature of fraud:\n",
    "\n",
    "[Fraud is an uncommon, well-considered, imperceptibly concealed, time-evolving and often carefully organized crime which appears in many types of forms .](https://www.amazon.com/Analytics-Descriptive-Predictive-Network-Techniques/dp/1119133122)\n",
    "\n",
    "\n",
    "This definition highlights the complex nature of the problems we must address when working on fraud systems.  First, fraud is *uncommon*.  Within any system of recorded transactions, only a small fraction of these transactions consist of fraudulent or illicit activities.  The sparse nature of these illicit activities complicates the nature of identifying these activities.  Second, fraud is *well-considered* and *imperceptibly concealed,* meaning that fraudulent activities are rarely impulsive activities.  Most fraudulent activities, at least at scale, involve multiple parties colluding together to perform actions specifically designed to exploit weaknesses in the system and elude detection.  Finally, fraud is *time-evolving*.  Fraudsters are continuously evolving and adapting their techniques as detection and prevention improve in an endless game of hide and seek.\n",
    "\n",
    "With these challenges in mind, many fraud detection systems take a multi-faceted approach to identifying illicit activities.   In this notebook, we will focus on identifying fraud rings through a guilt-by-association approach. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1bdbb3e",
   "metadata": {},
   "source": [
    "## Creating a fraud graph\n",
    "\n",
    "In this section we'll load a sample fraud graph and set some visualization options. We'll then use algorithms and openCypher queries to inspect the data model to look for patterns that indicate fraud ring activity.\n",
    "\n",
    "### Load data\n",
    "The cell below loads the example fraud graph into your graph. When you run the cell below, a graph for an example Fraud dataset will load, which will take less than 1 minute to load.\n",
    "\n",
    "To load this dataset, run the two cells below.  This first cell will setup a few python variables using the configuration parameters of this Neptune Notebook.  The second cell will use Neptune Analytics bulk load feature to load the data from the provided S3 bucket.  \n",
    "\n",
    "**Note:** You only need to do this once. If you have already loaded the data previously you do not need to load it again."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b0589d25",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import graph_notebook as gn\n",
    "config = gn.configuration.get_config.get_config()\n",
    "\n",
    "s3_bucket = f\"s3://aws-neptune-customer-samples-{config.aws_region}/sample-datasets/gremlin/Fraud/\"\n",
    "region = config.aws_region\n",
    "load_arn = config.load_from_s3_arn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e3987422",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc\n",
    "\n",
    "CALL neptune.load({format: \"csv\", \n",
    "                   source: \"${s3_bucket}\", \n",
    "                   region : \"${region}\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43fdc65f",
   "metadata": {},
   "source": [
    "### Set visualization and configuration options\n",
    "\n",
    "The cell below configures the visualization to use specific colors and icons for the different parts of the data model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "854a23c6",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%graph_notebook_vis_options\n",
    "\n",
    "{\n",
    "  \"groups\": {\n",
    "    \"Account\": {\n",
    "      \"shape\": \"icon\",\n",
    "      \"icon\": {\n",
    "        \"face\": \"'Font Awesome 5 Free'\",\n",
    "        \"weight\": \"bold\",\n",
    "        \"code\": \"\\uf2bb\",\n",
    "        \"color\": \"red\"\n",
    "      }\n",
    "    },\n",
    "    \"Transaction\": {\n",
    "      \"shape\": \"icon\",\n",
    "      \"icon\": {\n",
    "        \"face\": \"'Font Awesome 5 Free'\",\n",
    "        \"weight\": \"bold\",\n",
    "        \"code\": \"\\uf155\",\n",
    "        \"color\": \"green\"\n",
    "      }\n",
    "    },\n",
    "    \"Merchant\": {\n",
    "      \"shape\": \"icon\",\n",
    "      \"icon\": {\n",
    "        \"face\": \"'Font Awesome 5 Free'\",\n",
    "        \"weight\": \"bold\",\n",
    "        \"code\": \"\\uf290\",\n",
    "        \"color\": \"orange\"\n",
    "      }\n",
    "    },\n",
    "    \"DateOfBirth\": {\n",
    "      \"shape\": \"icon\",\n",
    "      \"icon\": {\n",
    "        \"face\": \"'Font Awesome 5 Free'\",\n",
    "        \"weight\": \"bold\",\n",
    "        \"code\": \"\\uf1fd\",\n",
    "        \"color\": \"blue\"\n",
    "      }\n",
    "    },\n",
    "    \"EmailAddress\": {\n",
    "      \"shape\": \"icon\",\n",
    "      \"icon\": {\n",
    "        \"face\": \"'Font Awesome 5 Free'\",\n",
    "        \"weight\": \"bold\",\n",
    "        \"code\": \"\\uf1fa\",\n",
    "        \"color\": \"blue\"\n",
    "      }\n",
    "    },\n",
    "    \"Address\": {\n",
    "      \"shape\": \"icon\",\n",
    "      \"icon\": {\n",
    "        \"face\": \"'Font Awesome 5 Free'\",\n",
    "        \"weight\": \"bold\",\n",
    "        \"code\": \"\\uf015\",\n",
    "        \"color\": \"blue\"\n",
    "      }\n",
    "    },\n",
    "    \"IpAddress\": {\n",
    "      \"shape\": \"icon\",\n",
    "      \"icon\": {\n",
    "        \"face\": \"'Font Awesome 5 Free'\",\n",
    "        \"weight\": \"bold\",\n",
    "        \"code\": \"\\uf109\",\n",
    "        \"color\": \"blue\"\n",
    "      }\n",
    "    },\n",
    "    \"PhoneNumber\": {\n",
    "      \"shape\": \"icon\",\n",
    "      \"icon\": {\n",
    "        \"face\": \"'Font Awesome 5 Free'\",\n",
    "        \"weight\": \"bold\",\n",
    "        \"code\": \"\\uf095\",\n",
    "        \"color\": \"blue\"\n",
    "      }\n",
    "    }\n",
    "  },\n",
    "  \"edges\": {\n",
    "    \"color\": {\n",
    "      \"inherit\": false\n",
    "    },\n",
    "    \"smooth\": {\n",
    "      \"enabled\": true,\n",
    "      \"type\": \"straightCross\"\n",
    "    },\n",
    "    \"arrows\": {\n",
    "      \"to\": {\n",
    "        \"enabled\": false,\n",
    "        \"type\": \"arrow\"\n",
    "      }\n",
    "    },\n",
    "    \"font\": {\n",
    "      \"face\": \"courier new\"\n",
    "    }\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5b4ce1c2",
   "metadata": {},
   "source": [
    "### Data model\n",
    "The fraud graph included in this example contains synthetic data that models credit card accounts, account holder information, merchants, and the transactions performed when an account holder purchases goods or services from a merchant.\n",
    "\n",
    "**Account and features**\n",
    "\n",
    "An Account has a number of features, including physical Address, IpAddress, DateOfBirth of the account holder, EmailAddress, and contact PhoneNumber. An account holder can have multiple email addresses and phone numbers.\n",
    "\n",
    "In many graph data models, these features of the account holder would be modelled as properties of the account. With fraud detection, it's important to be able to link accounts based on shared features, and to find related accounts at query time based on one or more shared features. Hence, our fraud detection application graph data model stores each feature as a separate vertex. Multiple accounts that share the same feature value - the same physical address, for example - are connected to the single vertex representing that feature value. \n",
    "\n",
    "The following query shows a single account and its associated features. After running the query, click the Graph tab to see a visualization of the results."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "59e92609",
   "metadata": {},
   "source": [
    "### What does a fraud graph look like for an account?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e9c3a2b3",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc -d value -l 20\n",
    "MATCH p=(n)-[]-()\n",
    "WHERE id(n)='account-4398046519460' \n",
    "RETURN p\n",
    "LIMIT 10"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "de43d125-f38e-40dd-a735-32870fb5638e",
   "metadata": {},
   "source": [
    "## Finding Fraud Rings in your graph\n",
    "\n",
    "Now that we have an idea what the data in our fraud graph looks like for an account, let's examine how you go about looking for fraud rings within data.\n",
    "\n",
    "Detecting fraud rings involves identifying unusual or suspicious patterns in data. These patterns can vary depending on the type of fraud and the context in which it occurs. Here are some common patterns that analysts and machine learning models might look for:\n",
    "\n",
    "* Unusual Behavior Patterns:\n",
    "    * Frequency: Unusually high or low transaction frequencies for certain accounts.\n",
    "    * Time of Activity: Transactions occurring at unusual times or outside regular business hours.\n",
    "    * Location: Transactions from unexpected or geographically distant locations.\n",
    "\n",
    "* Transaction Specifics:\n",
    "    * Transaction Amounts: Unusually large or small transactions compared to historical behavior.\n",
    "    * Transaction Types: Identifying unusual types of transactions for a specific user.\n",
    "    \n",
    "* Social Network Analysis:\n",
    "    * Connections: Identifying networks of accounts that frequently transact with each other.\n",
    "    * Topology Analysis: Examining the structure of connections between accounts.\n",
    "    \n",
    "These are just a few on the patterns you can look for to find fraud rings.  For this notebook we will be looking at detecting anomalous behavior using Social Network Analysis to find groups of accounts that are disproportionately highly connected with one another.  We will then use these groups to perform a topological analysis of these accounts by looking at the structure of the connections between the accounts.\n",
    "\n",
    "To begin this process we will start by running a graph algorithm that finds groups of highly connected nodes. Algorithms that accomplish this below to a category of algorithms called `Community Detection`.  Community detection algorithms calculate meaningful groups or clusters of nodes within a network, revealing hidden patterns and structures that can provide insights into the organization and dynamics of complex systems.\n",
    "\n",
    "There are a variety of supported community detection algorithms in Neptune Analytics and for this demonstration we will be using one known as **Label Propagation**\n",
    "\n",
    "The label propagation algorithm is a semi-supervised machine learning algorithm that assigns labels to nodes based on the consensus of their neighboring nodes.  This algorithm functions by assigning a label to a small subset of nodes.  These labels are then propagated to that nodes neighbors based on the maximum set of neighbor nodes.\n",
    "\n",
    "Label propagation can be an advantage when beginning fraud ring analysis as it does not require prior labeling of the communities.  However, it does have a disadvantage in that multiple runs of the same algorithm may yield different results, due to random assignment of initial starting nodes/labels.\n",
    "\n",
    "Let's run our label propagation algorithm and find out the size of the largest community in our graph.  We will also be storing the output of this algorithm for later analysis into a Python variable in the notebook named `community_data` using the `--store-to` switch on the `%%oc` magic."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "09ba869e-ab56-4c3f-a7d3-9fc82ccf3e4e",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc --store-to community_data\n",
    "\n",
    "MATCH (n)\n",
    "CALL neptune.algo.labelPropagation(n)\n",
    "YIELD community\n",
    "RETURN community, count(n) as size\n",
    "ORDER BY size DESC"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04e274a1-8259-4d46-9f87-93cd3f9c9fce",
   "metadata": {},
   "source": [
    "As we can see from the data above we have several communities that are around 300 members in size.  \n",
    "\n",
    "When looking for fraud rings within data the most common thing we want to look for is groupings that are anomalous to investigate.  In different domains, and even within different datasets within the same domain what constitutes an anomaly will vary.  When looking for fraud rings within data the most common thing we want to look for is groupings that are anomalous to investigate.  In different domains, and even within different datasets within the same domain what constitutes an anomaly will vary so a common way to determine what is \"normal\" in your particular data is to look at the distributions of communities.  \n",
    "\n",
    "\n",
    "To accomplish this we will use some Python libraries with the data we stored in the `community_data` variable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fc56bbb7-3960-40d1-a536-8d9b2f63ac83",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import plotly.express as px\n",
    "\n",
    "# Create a numpy histogram with the nubmer of bins being the max size\n",
    "df = pd.DataFrame(community_data['results'])\n",
    "hist = np.histogram(df.get('size'), bins=community_data['results'][0]['size'])\n",
    "\n",
    "# Plot the histogram using Plotly\n",
    "fig = px.bar(hist[0].tolist(), title = \"Community Size Distribution\")\n",
    "fig.update_layout(xaxis_title='Community Size', yaxis_title='Occurrences', title_x=0.5)\n",
    "fig.update_traces(showlegend=False)\n",
    "fig.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "818db47b-86ea-451b-bb9b-fa9670b42555",
   "metadata": {},
   "source": [
    "From the histogram chart above we can see that most of the communities in our on the small side, less than ~50 members.  What we also see is that a relatively small number of these communities have a large number of members, >300.\n",
    "\n",
    "Before we continue on though, let's take a moment and store the community value for each node back into our graph to simplify further analysis using a variation of the same algorithm.  This algorithm works the same except that this version stores the community value into a property specified, in this case the property name is `community`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c7ef849d-a632-4e3b-a1da-15aadc96f1aa",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc\n",
    "\n",
    "CALL neptune.algo.labelPropagation.mutate({writeProperty: 'community'})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e18f6320-e19c-42fe-b30d-cecb3635a504",
   "metadata": {},
   "source": [
    "Now that we have identified that large communities are the anomalies in our dataset, lets take a look at one of the communities, in this case we will look at the largest community in our graph."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d84e4dbc-1203-46b5-bcfd-ea387f69c4db",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc -g community\n",
    "\n",
    "MATCH (n) \n",
    "WITH n.community as community, count(n.community) as community_size \n",
    "ORDER BY community_size DESC LIMIT 1\n",
    "MATCH (n) WHERE n.community = community\n",
    "MATCH p=(n)-[]->()\n",
    "RETURN p"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea89c8e1-3bdd-48de-9184-34956670bd3c",
   "metadata": {},
   "source": [
    "Looking at the graph visualization above, we see that the community here is quite connected, as expected.  What we also see is that a few specific vertices are much more connected than the others.  This is what is known as \"centrality\" or \"influence\" in a graph.  \n",
    "\n",
    " Centrality in a graph refers to measures that identify the most important or central nodes in a network graph. Some common centrality measures include:\n",
    "\n",
    "- Degree centrality - Counts the number of edges connected to a node. Nodes with higher degree are more central or \"connected\" in the graph.\n",
    "\n",
    "- Closeness centrality - Calculates how close a node is to all other nodes by finding the shortest paths. Nodes with high closeness can spread information more quickly.\n",
    "\n",
    "- PageRank - A variant of eigenvector centrality used by Google Search to rank website importance. Important pages are those linked to by other important pages.\n",
    "\n",
    "In general, nodes with high centrality values are considered influential, visible, and critical to efficient network flow. Centrality helps identify the most important nodes to target in a network.  Each of the \n",
    "\n",
    "There are a variety of supported centrality algorithms in Neptune Analytics and for this demonstration we will be using one known as **Closeness Centrality**\n",
    "\n",
    " Closeness centrality is a measure of the average shortest path between a node and all other nodes in a network. It indicates how close a node is to the rest of the nodes in the network.\n",
    "\n",
    "The key points about closeness centrality are:\n",
    "\n",
    "- It measures how close a node is to all other nodes. Nodes with high closeness centrality can spread information faster as they have shorter paths to all others.\n",
    "\n",
    "- It is calculated as the inverse of the sum of the shortest paths between a node and all other nodes. Nodes with lower total distances to others have higher closeness centrality.\n",
    "\n",
    "- Nodes with high closeness centrality are able to communicate faster with the entire network. They are often influential nodes.\n",
    "\n",
    "- It is useful for identifying nodes that can distribute or receive information fastest to/from all others.\n",
    "\n",
    "- Differences in closeness centrality are more meaningful in larger networks. In small networks most nodes have similar closeness values.\n",
    "\n",
    "So in the case of our fraud graph, we have chosen to use high closeness centrality to find the nodes that are the influential or well-positioned nodes in a network to propagate fraudulent activities.\n",
    "\n",
    "Let's run our closeness centrality algorithm and find out the most import nodes within our graph."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f02a5645-3c88-41fc-951e-77c05a128eb1",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc\n",
    "\n",
    "MATCH (n) \n",
    "CALL neptune.algo.closenessCentrality(n, {numSources: 8192})\n",
    "YIELD score\n",
    "RETURN n, score \n",
    "ORDER BY score DESC LIMIT 1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c06c986a-0467-473c-a6db-bd3551a4c8f4",
   "metadata": {},
   "source": [
    "As with our earlier algorithms, we will run this again to store the centrality value back into our graph, this time in a property called `centrality`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e5f26b38-3e87-4273-9eac-2715e0925923",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc\n",
    "CALL neptune.algo.closenessCentrality.mutate({numSources: 8192, writeProperty: \"centrality\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3b70e20e-e3fb-47d8-84ed-f0647b07d0f8",
   "metadata": {},
   "source": [
    "## Examining a Fraud Ring\n",
    "\n",
    "Now that we have stored both the community value of our nodes as well as the relative importance, let's use this information to begin looking at a potential fraud ring.\n",
    "\n",
    "A common workflow for fraud ring investigation is to look at the most important node inside an anomalous communities.  In the case of our data, we have already determined that the largest communities are anomalous.  We can use this information combined with our centrality measurements to find a list of the 5 most important nodes to begin our investigation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0f759899-9730-4b0e-ac5a-e73ef1750f8e",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc -g community\n",
    "\n",
    "MATCH (n) \n",
    "WITH n.community as community, count(n.community) as community_size \n",
    "ORDER BY community_size DESC LIMIT 1\n",
    "MATCH (n) \n",
    "WHERE n.community = community\n",
    "RETURN n\n",
    "ORDER BY n.centrality DESC LIMIT 5"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c882feb8",
   "metadata": {},
   "source": [
    "### What if I only want to look at the nodes but their connections?\n",
    "\n",
    "While the node information is very important, determining what does and does not constitute fraud often requires looking at not just the data on the node, but how that node is connected to other entities in the graph.  To do that we can use graph traversals to see the connections to a node, which is known as a neighborhood in graphs.  \n",
    "\n",
    "Running the query below you will see retrieve the top 5 most important nodes in the largest community, as well as the entities within 2 neighborhoods of those nodes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ad0e5c6c",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc -g community -sd 30000\n",
    "\n",
    "MATCH (n) \n",
    "WITH n.community as community, count(n.community) as community_size \n",
    "ORDER BY community_size DESC LIMIT 1\n",
    "MATCH (n) \n",
    "WHERE n.community = community\n",
    "WITH n ORDER BY n.centrality DESC LIMIT 5\n",
    "MATCH p=(n)-[]-()-[]-()\n",
    "RETURN p"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "301adab7",
   "metadata": {},
   "source": [
    "## Analyzing the results\n",
    "\n",
    "\n",
    "A critical and ongoing part of any fraud workflow is to have a mechanism to enable analysts to investigate and prove/disprove that a potentially fraudulent activity exists.  \n",
    "\n",
    "Visual inspection, combined with the domain expertise of a fraud analyst, is a critical factor in being able to determine if anomalous patterns in a graph represent actual fraud or legitimate activity. Expert analysts are skilled in looking at the patterns of transactions and connections and the structural connections between items to determine the legitimacy of an account/transaction. Once they have made this determination, they will often flag these accounts/transactions as fraudulent in the graph to aid in future investigations.Visual inspection, combined with the domain expertise of a fraud analyst, is a critical factor in being able to determine if anomalous patterns in a graph represent actual fraud or legitimate activity. Expert analysts are skilled in looking at the patterns of transactions and connections and the structural connections between items to determine the legitimacy of an account/transaction. Once they have made this determination, they will often flag these accounts/transactions as fraudulent in the graph to aid in future investigations."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6d60c51f",
   "metadata": {},
   "source": [
    "### Mark as Fraud/Not Fraud\n",
    "\n",
    "In our scenario here let's assume that a domain expert has made a determination that the `merchant-48` node in our graph is a fraudulent.\n",
    "\n",
    "Let's mark the account above as fraudulent by setting the `isFraud` property to `True`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e4b36504",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc -d value -l 20\n",
    "MATCH (a)\n",
    "WHERE id(a)='merchant-48'\n",
    "SET a.isFraud=True\n",
    "RETURN a"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b11de2f",
   "metadata": {},
   "source": [
    "### Find all items within three hops of our fraudulent merchant\n",
    "\n",
    "Now that we have completed our investigation of `merchant-48` let's take a look at another account from our list above `merchant-48`.  In addition to looking at the connections, as shown above, another common use of graphs when analyzing anomalous activity is to look how closely an account is connected to a known fraudulent account. \n",
    "\n",
    "Let's take a look at this newly discovered fraudulent merchant and see what other items of interest we may way to investigate to look for other possible collusion."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "74dffa64",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "%%oc -d value -l 20\n",
    "\n",
    "MATCH p=(a)-[*1..3]-()\n",
    "WHERE a.isFraud=True\n",
    "RETURN p"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b37c65a0",
   "metadata": {},
   "source": [
    "Wow, there are a lot of shared connections and attributes to a known fraudster so it definitely looks suspicious, and is something we should continue to investigate.\n",
    "\n",
    "## Conclusion\n",
    "\n",
    "This notebook has shown how you can use Amazon Neptune Analytics to run analytics on your data to detect fraud rings. We've used a credit card dataset with account- and transaction-centric queries to perform a graph based fraud ring analysis based on a guilt-by-associated approach.  We first identified the groups in our data.  We then identified the most influential nodes within these groups and stored this information within our graph.  Using this information we were able to explore the connections around the most influential entities to identify other potentially fraudulent accounts.\n",
    "\n",
    "Combating fraud is an ongoing challenge for any organization.  The faster a team can identify fraud and the more they do, the more efficient anti-fraud systems become, preventing significant financial losses.  Finding and understanding fraud rings is a problem that requires the ability to query, analyze, and explore the connections between accounts, transactions, and account features.  Combining the ability to query a graph with the ability to run network analysis and graph algorithms on top of that data enables us to derive novel insights from this data. "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  },
  "vscode": {
   "interpreter": {
    "hash": "a974f8b3b9f8334bb022754c2deb5119d965db26467015db28878a5b98c93519"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
